home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / antipolix-2.0 / server.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-22  |  26.5 KB  |  1,026 lines

  1. #include <sys/types.h>
  2. #include <sys/time.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <math.h>
  10. #include <memory.h>
  11. #include <signal.h>
  12. #include <values.h>
  13.  
  14. #include "messages.h"
  15. #include "creation.h"
  16. #include "game.h"
  17.  
  18. typedef struct sockaddr *cliaddr;
  19.  
  20. typedef struct
  21. {
  22.     char Mesg[MESSAGE_BUF];
  23.     int FromWho;
  24. } MemoMesg;
  25.  
  26.  
  27. Parameters s_params={30, 100, 10, 10, 12, 3, 2, 10, 10, 5, 2, 1, 2, 1, 1, 2, 4};
  28.  
  29. int Queue[MAX_QUEUES];             /* nombre d'attentes dans chaque queue */
  30. int GoodForPlay[MAX_QUEUES];         /* nombre de joueurs souhaite pour chaque queue */
  31. cliaddr Clients[MAX_QUEUES][MAX_USERS];
  32. int Sockets[MAX_QUEUES][MAX_USERS];
  33. char Names[MAX_QUEUES][MAX_USERS][NAME_BUF];
  34. int V[MAX_QUEUES][MAX_USERS];
  35. char Emails[MAX_QUEUES][MAX_USERS][EMAILENGTH];
  36.  
  37. #define MAX_MOTD_LINES 30               /* Message of the day */
  38. static char Motd[MAX_MOTD_LINES][MESSAGE_BUF];
  39. static int nb_motd_lines;
  40.  
  41. int DeathCptr, FirstDead;
  42.  
  43. int ReadMotdFile()
  44. {
  45.   FILE *File;
  46.   char buf[MESSAGE_BUF];
  47.   int n;
  48.  
  49.   File=fopen(".motd", "r");
  50.   for (n=0; n<MAX_MOTD_LINES && fgets(Motd[n], MESSAGE_BUF, File)!=NULL; n++)
  51.     Motd[n][strlen(Motd[n])-1]='\0';
  52.   fclose(File);
  53.   return n;
  54. }
  55.  
  56. void SendMotd(int sockfd)  
  57. {
  58.   int i;
  59.   char buf[MESSAGE_BUF];
  60.  
  61.   PutInt(buf, nb_motd_lines);
  62.   write(sockfd, buf, ENTIER_BUF);
  63.  
  64.   for (i=0; i<nb_motd_lines; i++)
  65.     write(sockfd, Motd[i], MESSAGE_BUF);
  66. }
  67.  
  68. void SendQueueValues(int sockfd)
  69. {
  70.   char buf[ENTIER_BUF];
  71.   int i;
  72.  
  73.   PutInt(buf, MAX_QUEUES);
  74.   write(sockfd, buf, ENTIER_BUF);
  75.   
  76.   for (i=0; i<MAX_QUEUES; i++)
  77.     {
  78.       PutInt(buf, Queue[i]);
  79.       write(sockfd, buf, ENTIER_BUF);
  80.       PutInt(buf, GoodForPlay[i]);
  81.       write(sockfd, buf, ENTIER_BUF);
  82.     }
  83. }
  84.  
  85.  
  86. void ReadDefaultFile(Parameters *params)
  87. {
  88.   FILE *File;
  89.   char buf[100];
  90.   int n;
  91.  
  92.   File=fopen(".server_defaults", "r");
  93.   while (fscanf(File, "%s %d\n", buf, &n)>0)
  94.     {
  95.       if (!strcmp(buf, "SIZE_X"))
  96.     params->SIZE_X=n;
  97.       else if (!strcmp(buf, "SIZE_Z"))
  98.     params->SIZE_Z=n;
  99.       else if (!strcmp(buf, "COST_FORTRESS"))
  100.     params->COST_FORTRESS=n;
  101.       else if (!strcmp(buf, "COST_ARMIE"))
  102.     params->COST_ARMIE=n;
  103.       else if (!strcmp(buf, "COST_HOVERCRAFT"))
  104.     params->COST_HOVERCRAFT=n;
  105.       else if (!strcmp(buf, "COST_INVISIBILITY"))
  106.     params->COST_INVISIBILITY=n;
  107.       else if (!strcmp(buf, "COST_TELEPORT"))
  108.     params->COST_TELEPORT=n;
  109.       else if (!strcmp(buf, "DEF_FORTRESS"))
  110.     params->DEF_FORTRESS=n;
  111.       else if (!strcmp(buf, "DEF_ARMIE"))
  112.     params->DEF_ARMIE=n;
  113.       else if (!strcmp(buf, "DEF_HOVERCRAFT"))
  114.     params->DEF_HOVERCRAFT=n;
  115.       else if (!strcmp(buf, "ATT_ARMIE"))
  116.     params->ATT_ARMIE=n;
  117.       else if (!strcmp(buf, "ATT_HOVERCRAFT"))
  118.     params->ATT_HOVERCRAFT=n;
  119.       else if (!strcmp(buf, "MOV_ARMIE"))
  120.     params->MOV_ARMIE=n;
  121.       else if (!strcmp(buf, "MOV_HOVERCRAFT"))
  122.     params->MOV_HOVERCRAFT=n;
  123.       else if (!strcmp(buf, "TELEPORT_FIELD"))
  124.     params->TELEPORT_FIELD=n;
  125.       else if (!strcmp(buf, "TIME"))
  126.     params->TIME=n;
  127.       else if (!strcmp(buf, "CREDITS_100"))
  128.     params->CREDITS_100=n;
  129.     }
  130.   fclose(File);
  131. }
  132.  
  133.  
  134. void SendUniverseParameters(int sockfd, Parameters *params)
  135. {
  136.   char buf[ENTIER_BUF];
  137.  
  138.   PutInt(buf, params->TIME);
  139.   write(sockfd, buf, ENTIER_BUF);
  140.   PutInt(buf, params->CREDITS_100);
  141.   write(sockfd, buf, ENTIER_BUF);
  142.   PutInt(buf, params->SIZE_X);
  143.   write(sockfd, buf, ENTIER_BUF);
  144.   PutInt(buf, params->SIZE_Z);
  145.   write(sockfd, buf, ENTIER_BUF);
  146.   PutInt(buf, params->COST_FORTRESS);
  147.   write(sockfd, buf, ENTIER_BUF);
  148.   PutInt(buf, params->COST_ARMIE);
  149.   write(sockfd, buf, ENTIER_BUF);
  150.   PutInt(buf, params->COST_HOVERCRAFT);
  151.   write(sockfd, buf, ENTIER_BUF);
  152.   PutInt(buf, params->COST_INVISIBILITY);
  153.   write(sockfd, buf, ENTIER_BUF);
  154.   PutInt(buf, params->COST_TELEPORT);
  155.   write(sockfd, buf, ENTIER_BUF);
  156.   PutInt(buf, params->DEF_FORTRESS);
  157.   write(sockfd, buf, ENTIER_BUF);
  158.   PutInt(buf, params->DEF_ARMIE);
  159.   write(sockfd, buf, ENTIER_BUF);
  160.   PutInt(buf, params->DEF_HOVERCRAFT);
  161.   write(sockfd, buf, ENTIER_BUF);
  162.   PutInt(buf, params->ATT_ARMIE);
  163.   write(sockfd, buf, ENTIER_BUF);
  164.   PutInt(buf, params->ATT_HOVERCRAFT);
  165.   write(sockfd, buf, ENTIER_BUF);
  166.   PutInt(buf, params->MOV_ARMIE);
  167.   write(sockfd, buf, ENTIER_BUF);
  168.   PutInt(buf, params->MOV_HOVERCRAFT);
  169.   write(sockfd, buf, ENTIER_BUF);
  170.   PutInt(buf, params->TELEPORT_FIELD);
  171.   write(sockfd, buf, ENTIER_BUF);
  172. }
  173.  
  174.  
  175. void SendTimer(int sockfd, int sablier)
  176. {
  177.   char buf[SABLIER_BUF];
  178.  
  179.   SendEntete(sockfd, SABLIER);
  180.   PutInt(buf, sablier);
  181.   write(sockfd, buf, SABLIER_BUF);
  182. }
  183.  
  184.  
  185. void EnvoiCasesPrises(int sockfd, Univers *U)
  186. {
  187.   Univers U2;
  188.   int i, j, k;
  189.  
  190.   /* Pour ne pas envoyer trop d'informations au client */
  191.   CreateUniverse(&U2, U->NbPlateaux, U->P[0].Taille);
  192.   CopyUniverse(&U2, U);
  193.   for (i=0; i<U2.NbPlateaux; i++)
  194.     for (j=0; j<U2.P[i].Taille; j++)
  195.       for (k=0; k<U2.P[i].Taille; k++)
  196.     if (U2.P[i].Case[j][k].Type >= 0)
  197.       {
  198.         U2.P[i].Case[j][k].Type=(CASE_OCCUPEE); /* seule la couleur est envoyee au client. */
  199.         U2.P[i].Case[j][k].Couleur=(CASE_OCCUPEE);
  200.       }
  201.   SendUniverse(sockfd, &U2);
  202. }
  203.  
  204.  
  205. void AffecteSabliers(int nbplayers, int Sabliers[MAX_USERS])
  206. {
  207.   int i, chaque;
  208.  
  209.   if (nbplayers*s_params.TIME > MAX_TOT_TIME)
  210.     chaque=MAX_TOT_TIME/nbplayers;
  211.   else
  212.     chaque=s_params.TIME;
  213.  
  214.   for (i=0; i<nbplayers; i++)
  215.     Sabliers[i]=chaque;
  216. }
  217.  
  218.  
  219. void MovePiece(Univers *U, Case Depart, Case Arrivee)
  220. {
  221.   int p=Depart.p, x=Depart.x, y=Depart.y;
  222.  
  223.   if (IsNear(U, Depart, Arrivee, U->P[p].Case[x][y].Type, &s_params))
  224.     {
  225.       U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Couleur=U->P[p].Case[x][y].Couleur;
  226.       U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Type=U->P[p].Case[x][y].Type;
  227.       U->P[Arrivee.p].Case[Arrivee.x][Arrivee.y].Caract=U->P[p].Case[x][y].Caract;
  228.       U->P[p].Case[x][y].Couleur=CASE_VIDE;
  229.       U->P[p].Case[x][y].Type=CASE_VIDE;
  230.       U->P[p].Case[x][y].Caract=NORMAL;
  231.     }
  232. }
  233.  
  234. int GetRandomNumber(int Max)
  235. {
  236.   int i, m2;
  237.  
  238.   m2=Max*2;
  239.   i=random();
  240.   while (i>m2)
  241.     i=i/2;
  242.   return i-Max;
  243. }
  244.  
  245.  
  246. void SaveName(char *Name, char *Password, int V)
  247. {
  248.   FILE *File;
  249.   int LineSize=NAME_BUF+PASSLENGTH+szi+2, i=0;
  250.   char *Line, *Line2, buf[szi];
  251.  
  252.   Line=malloc(LineSize);
  253.   Line2=malloc(LineSize);
  254.   PutInt(buf, V);
  255.   
  256.   File=fopen(".players", "r+");
  257.   
  258.   while (fread(Line2, LineSize, 1, File) && strncmp(Name, Line2, NAME_BUF))
  259.     i++;
  260.   memcpy(Line, Name, NAME_BUF);
  261.   if (Password==NULL)
  262.     memcpy(Line+NAME_BUF, Line2+NAME_BUF, PASSLENGTH);
  263.   else
  264.     memcpy(Line+NAME_BUF, Password, PASSLENGTH);
  265.   memcpy(Line+NAME_BUF+PASSLENGTH, buf, szi);
  266.   Line[LineSize-1]='\n';
  267.   rewind(File);
  268.   fseek(File, i*LineSize, 0);
  269.   fwrite(Line, LineSize, 1, File);
  270.   
  271.   fclose(File);
  272. }
  273.  
  274. void InformeJoueurs(int joueur, int *Socket, char *Message, int ErrorType, int nbplayers, 
  275.             char PNames[MAX_USERS][NAME_BUF])
  276. {
  277.   int i, j;
  278.   char msg[10];
  279.   
  280.   for (i=0; i<nbplayers; i++)
  281.     if (i!=joueur && Socket[i]>=0)
  282.       {
  283.     SendMessage(Socket[i], Message, -1);
  284.     PutInt(msg, ErrorType);
  285.     PutInt(msg+szi, joueur);
  286.     SendMessage(Socket[i], msg, -1);
  287.       }
  288. }
  289.  
  290. void RegisterDead(int dead, int nbplayers, int *V)
  291. {
  292.   V[dead]-=(nbplayers-DeathCptr); 
  293.   V[dead]=(V[dead]<0?0:V[dead]);
  294.   if (!DeathCptr)
  295.     FirstDead=dead;
  296.   DeathCptr++;
  297. }
  298.  
  299. int AttackPiece(Univers *U, OneMovement Move, int movenumber, int joueur, int Socket[MAX_USERS],
  300.         int nbplayers, char PNames[MAX_USERS][NAME_BUF], int *V)
  301. {
  302.   int i, j, Montot=0, Sontot=0, MemoEnnemy, MemoType, MemoCaract;
  303.   Case c, memo, amove;
  304.   
  305.   for (i=0; i<Move.nbcases; i++)
  306.     {
  307.       c=Move.cases[i];
  308.       if (IsWhom(U, c.p, c.x, c.y, joueur)==ENNEMY)
  309.     {
  310.       memo=c;
  311.       i=Move.nbcases; /* on sort de la boucle */
  312.     }
  313.     }
  314.   MemoEnnemy=U->P[c.p].Case[c.x][c.y].Couleur;
  315.   MemoType=U->P[c.p].Case[c.x][c.y].Type;
  316.   MemoCaract=U->P[c.p].Case[c.x][c.y].Caract;
  317.  
  318.   for (i=0; i<Move.nbcases; i++)
  319.     {
  320.       c=Move.cases[i];
  321.       if (IsWhom(U, c.p, c.x, c.y, joueur)==MYARMIE && 
  322.       IsNear(U, c, memo, U->P[c.p].Case[c.x][c.y].Type, &s_params))
  323.     {
  324.       amove=c;
  325.       switch(U->P[c.p].Case[c.x][c.y].Type)
  326.         {
  327.         case ARMEE:
  328.           Montot+=s_params.ATT_ARMIE;
  329.           break;
  330.         case HOVERCRAFT:
  331.           Montot+=s_params.ATT_HOVERCRAFT;
  332.           break;
  333.         }
  334.     }
  335.     }
  336.  
  337.   if (Montot==0)
  338.     return 0;
  339.   
  340.   if (U->P[memo.p].Case[memo.x][memo.y].Caract==INVISIBLE)
  341.     {
  342.       if (U->P[memo.p].Case[memo.x][memo.y].Type!=FORTERESSE)
  343.     {
  344.       MovePiece(U, amove, memo);  /* piece invisible "ecrasee" */
  345.       return 1;
  346.     }
  347.       else
  348.     return 0; /* on n'ecrase pas une forteresse invisible ! */
  349.     }
  350.   
  351.   Sontot=DefenseTotal(U, memo.p, memo.x, memo.y, &s_params);
  352.   if (Montot>Sontot)
  353.     {
  354.       char message[100], *detail;
  355.       int Chance, Dp, Dx, Dy, Sort;
  356.       
  357.       Chance=GetRandomNumber(100);
  358.       if (Chance<40) /* ------ 40% de chances d'eliminer la piece */
  359.     {
  360.       U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
  361.       U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
  362.       U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
  363.       Sort=0;
  364.     }
  365.       else if (Chance<70) /* 30% de chances de la faire basculer de camps */
  366.     {
  367.       if (MemoCaract!=CHEF)
  368.         U->P[memo.p].Case[memo.x][memo.y].Couleur=joueur;
  369.       Sort=1;
  370.     }
  371.       else         /* ----- 30% de chances de la randoteleporter... */
  372.     {
  373.       Dp=GetRandomNumber(U->NbPlateaux-1);
  374.       Dx=GetRandomNumber(U->P[0].Taille-1);
  375.       Dy=GetRandomNumber(U->P[0].Taille-1);
  376.       if (IsWhom(U, Dp, Dx, Dy, joueur)!=CASE_VIDE)
  377.         {   /* --------- piece supprimee ----------- */
  378.           U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
  379.           U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
  380.           U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
  381.           Sort=0;
  382.         }
  383.       else
  384.         {  /* ---------- piece teleportee ------------ */
  385.           U->P[Dp].Case[Dx][Dy].Couleur=U->P[memo.p].Case[memo.x][memo.y].Couleur;
  386.           U->P[Dp].Case[Dx][Dy].Type=U->P[memo.p].Case[memo.x][memo.y].Type;
  387.           U->P[Dp].Case[Dx][Dy].Caract=U->P[memo.p].Case[memo.x][memo.y].Caract;
  388.           U->P[memo.p].Case[memo.x][memo.y].Couleur=CASE_VIDE;
  389.           U->P[memo.p].Case[memo.x][memo.y].Type=CASE_VIDE;
  390.           U->P[memo.p].Case[memo.x][memo.y].Caract=NORMAL;
  391.           Sort=2;
  392.         }
  393.     }
  394.       if (Sort==0)
  395.     detail="Unit destroyed";
  396.       else if (Sort==1)
  397.     detail="Unit switched owner";
  398.       else
  399.     detail="Unit randoteleported";
  400.  
  401.       sprintf(message, "Attack Movement No %d Successful (%s)", movenumber, detail);
  402.       SendMessage(Socket[joueur], message, -1);
  403.       sprintf(message, "Attack From %d On [%d %d %d] : Defense Failed (%s)", 
  404.           joueur, memo.p, memo.x, memo.y, detail);
  405.       SendMessage(Socket[MemoEnnemy], message, -1);
  406.  
  407.       if ((Sort==0 || Sort==1) && MemoCaract==CHEF)
  408.     {
  409.       char Message[MESSAGE_BUF];
  410.       SendMessage(Socket[MemoEnnemy], "You have been kilLed... R.I.P :-)", -1);
  411.       SendEntete(Socket[MemoEnnemy], DEBLOCK);
  412.       close(Socket[MemoEnnemy]);
  413.       Socket[MemoEnnemy]=(-1);
  414.       RegisterDead(MemoEnnemy, nbplayers, V);
  415.       ChangeToPlayer(U, MemoEnnemy, joueur);
  416.       sprintf(Message, "Player (%d)%s has been killed by (%d)%s", 
  417.           MemoEnnemy, PNames[MemoEnnemy], joueur, PNames[joueur]);
  418.       InformeJoueurs(MemoEnnemy, Socket, Message, KILLED, nbplayers, PNames);
  419.     }
  420.       return 1;
  421.     }
  422.   else
  423.     {
  424.       char message[100];
  425.       sprintf(message, "Attack Movement No %d Failed", movenumber);
  426.       SendMessage(Socket[joueur], message, -1);
  427.       sprintf(message, "Attack From %d On [%d %d %d] : Defense Successful", 
  428.           joueur, memo.p, memo.x, memo.y);
  429.       SendMessage(Socket[MemoEnnemy], message, -1);
  430.       return 0;
  431.     }
  432. }
  433.   
  434.  
  435.  
  436. void ChangeUniverse(Univers *U, OneMovement *Moves, int joueur, int Socket[MAX_USERS], 
  437.             int nbplayers, char PNames[MAX_USERS][NAME_BUF], int *V)
  438. {
  439.   int i, j, myarmies=0, ennemies=0, vides=0;
  440.   
  441.   /* ------ verification que chaque case est utilisee une seule fois -------- */
  442.   for (i=0; i<NB_MOVES; i++)
  443.     for (j=0; j<Moves[i].nbcases; j++)
  444.       if (!IsUnique(Moves, i, j+1, Moves[i].cases[j].p, Moves[i].cases[j].x, Moves[i].cases[j].y))
  445.     {
  446.       SendMessage(Socket[joueur], "Bad Movement", -1);
  447.       return;
  448.     }
  449.  
  450.   for (i=0; i<NB_MOVES; i++)
  451.     if (Moves[i].nbcases)
  452.       {
  453.     myarmies=0; ennemies=0; vides=0;
  454.     for (j=0; j<Moves[i].nbcases; j++)
  455.       {
  456.         Case c=Moves[i].cases[j];
  457.         int r=IsWhom(U, c.p, c.x, c.y, joueur);
  458.         if (r==CASE_VIDE)
  459.           vides++;
  460.         else if (r==MYARMIE)
  461.           myarmies++;
  462.         else if (r==ENNEMY)
  463.           ennemies++;
  464.         else
  465.           StopError(5678);
  466.       }
  467.     if (vides==1 && myarmies==1 && ennemies==0) /*   --------- Deplacement  -------------- */
  468.       {
  469.         if (IsWhom(U, Moves[i].cases[0].p, Moves[i].cases[0].x, Moves[i].cases[0].y, joueur)
  470.         == CASE_VIDE)
  471.           MovePiece(U, Moves[i].cases[1], Moves[i].cases[0]);
  472.         else
  473.           MovePiece(U, Moves[i].cases[0], Moves[i].cases[1]);
  474.       }
  475.     else if (vides==0 && myarmies>0 && ennemies==1) /* ------------- Attaque -------------- */
  476.       AttackPiece(U, Moves[i], i, joueur, Socket, nbplayers, PNames, V);
  477.     else
  478.       {
  479.         char message[40];
  480.         sprintf(message, "Bad movement");  /* bad movement no (i+1) */
  481.         SendMessage(Socket[joueur], message, -1);
  482.       }
  483.       }
  484. }
  485.  
  486.  
  487. void BadDataProcedure(int joueur, char PNames[MAX_USERS][NAME_BUF], 
  488.               int *Socket, int *V, int nbplayers)
  489. {
  490.   char Message[MESSAGE_BUF];
  491.   
  492.   SendMessage(Socket[joueur], "** Bad data... ciao !!", -1);
  493.   close(Socket[joueur]);
  494.   Socket[joueur]=(-1);
  495.   RegisterDead(joueur, nbplayers, V);
  496.   sprintf(Message, "Connection error with player (%d)%s", joueur, PNames[joueur]);
  497.   InformeJoueurs(joueur, Socket, Message, DATAERROR, nbplayers, PNames);
  498. }
  499.  
  500.  
  501. void TraiteMessage(Univers *U, char *Message, int Socket[MAX_USERS], 
  502.            int ForWho, int FromWho, int nbplayers, char PNames[MAX_USERS][NAME_BUF],
  503.            int *NbAlive, int *OKForNul, int *V)
  504. {
  505.   char mesg[MESSAGE_BUF];
  506.   int i, r;
  507.   
  508.   if (ForWho==-1) /* message pour le serveur */
  509.     if (!strcmp(Message, "QUIT"))
  510.       {
  511.     SendEntete(Socket[FromWho], DEBLOCK);
  512.     close(Socket[FromWho]);
  513.     Socket[FromWho]=(-1);
  514.     RegisterDead(FromWho, nbplayers, V);
  515.     sprintf(mesg, "Player (%d)%s Gives Up", FromWho, PNames[FromWho]);
  516.     InformeJoueurs(FromWho, Socket, mesg, ABANDON, nbplayers, PNames);
  517.     ErasePlayer(U, FromWho);
  518.     (*NbAlive)--;
  519.       }
  520.     else if (!strcmp(Message, "NUL"))
  521.       {
  522.     sprintf(mesg, "Player (%d)%s propose nul game", FromWho, PNames[FromWho]);
  523.     InformeJoueurs(FromWho, Socket, mesg, NOT_A_DEATH, nbplayers, PNames);
  524.     OKForNul[FromWho]=1;
  525.     for (r=1, i=0; i<nbplayers; i++)
  526.       if (!OKForNul[i])
  527.         r=0;
  528.     if (r)  /* si tous les joueurs ont demande match nul... MATCH NUL */
  529.       {
  530.         sprintf(mesg, "** NUL GAME -- Nobody wins **");
  531.         for (i=0; i<nbplayers; i++)
  532.           if (Socket[i]>=0) {
  533.         SendMessage(Socket[i], mesg, -1);
  534.         SendEntete(Socket[i], DEBLOCK);
  535.         close(Socket[i]); }
  536.         exit(0);  /* ---------- THE END (match nul) ---- Les scores ne sont pas sauvegardes */
  537.       }
  538.       }
  539.     else if (!strcmp(Message, "WAR"))
  540.       {
  541.     sprintf(mesg, "Player (%d)%s cancels any previous nul game proposition", 
  542.         FromWho, PNames[FromWho]);
  543.     InformeJoueurs(FromWho, Socket, mesg, NOT_A_DEATH, nbplayers, PNames);
  544.     OKForNul[FromWho]=0;
  545.       }
  546.     else
  547.       Message[MESSAGE_BUF-1]='\0';
  548.   
  549.   else if (ForWho==-2) {
  550.     for (i=0; i<nbplayers; i++)
  551.       if (Socket[i]>0 && i!=FromWho)
  552.     SendMessage(Socket[i], Message, (FromWho+1)*100); }
  553.   else if (ForWho>=nbplayers || ForWho<0 || Socket[ForWho]<0 || !IsVoisin(U, FromWho, ForWho))
  554.     SendMessage(Socket[FromWho], "Can't reach this player", -1);
  555.   else
  556.     SendMessage(Socket[ForWho], Message, FromWho);
  557. }
  558.  
  559.  
  560. void TesteVictoire(int nbplayers, int Socket[MAX_USERS], char PNames[MAX_USERS][NAME_BUF], 
  561.            int V[MAX_USERS])
  562. {
  563.   int cpt=0, i, j;
  564.   
  565.   for (i=0; i<nbplayers; i++)
  566.     if (Socket[i]>=0)
  567.       cpt++;
  568.   
  569.   if (!cpt)
  570.     exit(0);
  571.  
  572.   if (cpt==1)   /* ------- il ne reste plus qu'un joueur ------- */
  573.     {
  574.       for (i=0; i<nbplayers && Socket[i]<0; i++);
  575.       SendMessage(Socket[i], "You win !", -1);
  576.       SendEntete(Socket[i], DEBLOCK);
  577.       close(Socket[i]);
  578.           
  579.       V[i]+=nbplayers; /* le gagnant ... */
  580.       if (nbplayers>3)
  581.     V[FirstDead]=0;  /* le premier mort d'un match a plus de trois joueurs est resete' */
  582.       
  583.       for (i=0; i<nbplayers; i++)  /* sauvegarde des points */
  584.     SaveName(PNames[i], NULL, V[i]);
  585.       
  586.       exit(0);  /* ------------- THE END --------------- */
  587.     }
  588. }
  589.  
  590.  
  591. void BeginTheGameServer(int NBPLX, cliaddr Client[MAX_USERS], int Socket[MAX_USERS], 
  592.             int nbplayers, char PNames[MAX_USERS][NAME_BUF], int V[MAX_USERS],
  593.             char Email[MAX_USERS][EMAILENGTH])
  594. {
  595.   char buf[QUEUE_BUF], Message[MESSAGE_BUF], Entete[ENTETE_BUF], Sabuf[SABLIER_BUF];
  596.   int i, j, mesg, joueur, Who, CONTINUE, Resultat, Sabliers[MAX_USERS], PECULE, cpt;
  597.   int Order[MAX_USERS], GrainM=0, GrainP=0, PlayerOK[MAX_USERS], NbAlive, OKForNul[MAX_USERS];
  598.   Univers U, U2;
  599.   OneMovement Moves[MAX_USERS][NB_MOVES];
  600.  
  601.   for (i=0; i<nbplayers; i++)
  602.     OKForNul[i]=0;
  603.   DeathCptr=1;
  604.  
  605.   srand(clock()); /* initialisation du generateur d'"aleation" */
  606.   CreateUniverse(&U, NBPLX, s_params.SIZE_X);
  607.   CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
  608.   AffecteSabliers(nbplayers, Sabliers);
  609.  
  610.   /* ----- ENVOI de la valeur du sablier (<=> "Go !")  ---------------------- */
  611.   for (i=0; i<nbplayers; i++)
  612.     {
  613.       PutInt(Sabuf, Sabliers[i]);
  614.       write(Socket[i], Sabuf, SABLIER_BUF);
  615.     }
  616.  
  617.   /* ----- ENVOI des noms des joueurs --------------------------------------- */
  618.   for (i=0; i<nbplayers; i++)
  619.     for (j=0; j<nbplayers; j++)
  620.       write(Socket[i], PNames[j], NAME_BUF);
  621.   
  622.   /* ----- ENVOI des emails des joueurs --------------------------------------- */
  623.   for (i=0; i<nbplayers; i++)
  624.     for (j=0; j<nbplayers; j++)
  625.       write(Socket[i], Email[j], EMAILENGTH);
  626.  
  627.   /* ----- ENVOI des scores des joueurs --------------------------------------- */
  628.   for (i=0; i<nbplayers; i++)
  629.     for (j=0; j<nbplayers; j++) {
  630.       PutInt(buf, V[j]);
  631.       write(Socket[i], buf, ENTIER_BUF); }
  632.   
  633.   PECULE=NBPLX*s_params.SIZE_X*s_params.SIZE_X/100*s_params.CREDITS_100/nbplayers;
  634.   PutInt(buf, PECULE);
  635.   for (i=0; i<nbplayers; i++)
  636.     {
  637.       PutInt(buf+szi, i);  /* la position du joueur */
  638.       write(Socket[i], buf, QUEUE_BUF);
  639.       EnvoiCasesPrises(Socket[i], &U);
  640.       if (WaitForThisSocket(Socket[i], 100))
  641.     /* 5 minutes pour placer les pieces */
  642.     {
  643.       if (GetEntete(Socket[i])==UNIVERS)
  644.         {
  645.           GetUniverse(Socket[i], &U2);
  646.           CopyUniverse(&U, &U2);
  647.         }
  648.       else  /* ne doit pas arriver (erreur de transmission...) */
  649.         {
  650.           SendEntete(Socket[i], DEBLOCK);
  651.           close(Socket[i]);
  652.           Socket[i]=(-1);
  653.           RegisterDead(i, nbplayers, V);
  654.         }
  655.     }
  656.       else
  657.     {
  658.       SendEntete(Socket[i], DEBLOCK);
  659.       close(Socket[i]);
  660.       Socket[i]=(-1); /* joueur elimine si delai ecoule */
  661.       RegisterDead(i, nbplayers, V);
  662.     }
  663.     }
  664.  
  665.   /*  ------------------ Begining of GAME ----------------------------------- */
  666.  
  667.   NbAlive=0;
  668.   for (i=0; i<nbplayers; i++)
  669.     if (Socket[i]>=0)
  670.       {
  671.     Univers U2;
  672.     CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
  673.     CopyUniverse(&U2, &U);
  674.     TransformUniverse(&U2, i);
  675.     SendUniverse(Socket[i], &U2);
  676.     NbAlive++;
  677.       }
  678.   
  679.   if (!NbAlive)  /* plus de joueurs !! */
  680.     exit(0);
  681.  
  682.   while(1)
  683.     {
  684.       int NBOK=0;
  685.       TesteVictoire(nbplayers, Socket, PNames, V);
  686.  
  687.       for (joueur=0; joueur<nbplayers; joueur++) /* On envoie le coup de depart */
  688.     if (Socket[joueur]!=-1)
  689.       SendEntete(Socket[joueur], MY_TURN);
  690.  
  691.       for (i=0; i<nbplayers; i++)
  692.     PlayerOK[i]=0;
  693.  
  694.       GrainP=0; GrainM=0;
  695.  
  696.       while (NBOK<NbAlive)  /* ---- chaque seconde ---- */
  697.     {
  698.       sleep(1);
  699.       for (joueur=0; joueur<nbplayers; joueur++) /* - pour chaque joueur - */
  700.         {
  701.           if (Socket[joueur]==-1)
  702.         continue;
  703.           
  704.           Resultat=WaitForThisSocket(Socket[joueur], 0);
  705.           if (Resultat)
  706.         {
  707.           mesg=GetEntete(Socket[joueur]);
  708.           if (mesg==MOVEMENT)
  709.             {
  710.               Order[NBOK]=joueur;
  711.               PlayerOK[joueur]=1;
  712.               GetMovement(Socket[joueur], Moves[NBOK]);
  713.               NBOK++;
  714.               GrainM=NBOK;
  715.               GrainP=NbAlive-NBOK;
  716.             }
  717.           else if (mesg==MESSAGE)
  718.             {
  719.               GetMessage(Socket[joueur], &Who, Message);
  720.               TraiteMessage(&U, Message, Socket, Who, joueur, nbplayers, PNames, 
  721.                     &NbAlive, OKForNul, V);
  722.             }
  723.           else /* (mesg!=MOVEMENT && mesg !=MESSAGE) */
  724.             {
  725.               BadDataProcedure(joueur, PNames, Socket, V, nbplayers);
  726.               ErasePlayer(&U, joueur);
  727.               NbAlive--;
  728.             }
  729.         }
  730.         }  /* --- fin pour chaque joueur ---- */
  731.  
  732.       for (i=0; i<nbplayers; i++) /* le sable coule... */
  733.         {
  734.           if (Socket[i]>0)
  735.         {
  736.           if (PlayerOK[i])
  737.             Sabliers[i]+=GrainP;
  738.           else
  739.             {
  740.               Sabliers[i]-=GrainM;
  741.               if (Sabliers[i]<=0)
  742.             {
  743.               SendMessage(Socket[i], "Time Death... You Lose !", -1);
  744.               SendEntete(Socket[i], DEBLOCK);
  745.               close(Socket[i]);
  746.               Socket[i]=(-1);
  747.               RegisterDead(i, nbplayers, V);
  748.               ErasePlayer(&U, i);
  749.               NbAlive--;
  750.               sprintf(Message, "Player (%d)%s Has Been Killed By Time", i, PNames[i]);
  751.               InformeJoueurs(i, Socket, Message, TIMEDEATH, nbplayers, PNames);
  752.             }
  753.             }
  754.           if (Socket[i]>=0)
  755.             SendTimer(Socket[i], Sabliers[i]);
  756.         }
  757.         }
  758.     }  /* ---  chaque seconde ---- */
  759.       
  760.       for (i=0; i<NBOK; i++)
  761.     ChangeUniverse(&U, Moves[i], Order[i], Socket, nbplayers, PNames, V);
  762.  
  763.       NbAlive=0;
  764.       for (i=0; i<NBOK; i++)   /* ------ Le serveur envoie le nouvel univers...  -------*/
  765.     if (Socket[Order[i]]>=0)
  766.       {
  767.         Univers U2;
  768.         CreateUniverse(&U2, NBPLX, s_params.SIZE_X);
  769.         CopyUniverse(&U2, &U);
  770.         TransformUniverse(&U2, Order[i]);
  771.         SendUniverse(Socket[Order[i]], &U2);
  772.         NbAlive++;
  773.       }
  774.     }
  775. }
  776.  
  777.  
  778. int LoadName(char *Name, char *Password)
  779. {
  780.   FILE *File;
  781.   int LineSize=NAME_BUF+PASSLENGTH+szi+2, IsOK=0;
  782.   char *Line;
  783.   int Value;
  784.  
  785.   Line=malloc(LineSize);
  786.  
  787.   File=fopen(".players", "r");
  788.   while(!IsOK)
  789.     {
  790.       if (!fread(Line, 1, LineSize, File))
  791.     IsOK=2;
  792.       else if (!strncmp(Name, Line, NAME_BUF))
  793.     IsOK=1;
  794.     }
  795.   fclose(File);
  796.   if (IsOK==2) /* le nom n'existe pas dans le fichier */
  797.     return 0;
  798.   memcpy(Password, Line+NAME_BUF, PASSLENGTH);
  799.   GetInt(Line+NAME_BUF+PASSLENGTH, &Value);
  800.   return Value;
  801. }
  802.  
  803. int ReceiveName(int sockfd, char *Name)
  804. {
  805.   int NameOK=0, V, i;
  806.   char Password[PASSLENGTH], buf[szi], Pass[PASSLENGTH];
  807.  
  808.   while (!NameOK)
  809.     {
  810.       if (MyRead(sockfd, Name, NAME_BUF, TIMEOUT)==-1)  /* RECOIT le NOM du joueur */
  811.     return -1;
  812.  
  813.       if (V=LoadName(Name, Password)) /* le nom existe */
  814.     {
  815.       PutInt(buf, 1234);
  816.       write(sockfd, buf, szi);
  817.       if (MyRead(sockfd, Pass, PASSLENGTH, TIMEOUT)==-1)
  818.         return -1;
  819.       if (!strncmp(Pass, Password, PASSLENGTH))
  820.         {
  821.           PutInt(buf, 5678);  /* password OK */
  822.           NameOK=1;
  823.         }
  824.       else
  825.         PutInt(buf, 2345);  /* password inexact */
  826.       write(sockfd, buf, szi);
  827.     }
  828.       else  /* le nom n'existe pas */
  829.     {
  830.       PutInt(buf, 2345);
  831.       write(sockfd, buf, szi);
  832.       if (MyRead(sockfd, buf, szi, TIMEOUT)==-1)
  833.         return -1;
  834.       GetInt(buf, &i);
  835.       if (i==8765)
  836.         {
  837.           if (MyRead(sockfd, Password, PASSLENGTH, TIMEOUT)==-1)
  838.         return -1;
  839.           SaveName(Name, Password, 1);
  840.           V=0;           /* score de depart a la creation des joueurs */
  841.           NameOK=1;
  842.         }
  843.     }
  844.     }
  845.   return V;
  846. }
  847.  
  848.  
  849. int GetWhichQueue(int sockfd, int desir, int nb_wanted, int *WhichQueue, 
  850.           char *Name, char *email, int Va)
  851. {
  852.   char buf[QUEUE_BUF];
  853.   int i, PPtr, NbInQueue=0;
  854.  
  855.   
  856.   for (i=0; i<Queue[desir]; i++)
  857.     if (Sockets[desir][i]==-1) 
  858.       {
  859.     PPtr=i;
  860.     i=Queue[desir]+1; 
  861.       }
  862.  
  863.   if (i==Queue[desir])
  864.     {
  865.       PPtr=Queue[desir];
  866.       Queue[desir]++;
  867.     }
  868.  
  869.   if (GoodForPlay[desir]==0)
  870.     GoodForPlay[desir]=nb_wanted;
  871.  
  872.   strncpy(Names[desir][PPtr], Name, NAME_BUF); /* le NOM */
  873.   Sockets[desir][PPtr]=sockfd;  /* memorise le SOCKET du client */
  874.   strncpy(Emails[desir][PPtr], email, EMAILENGTH);
  875.   V[desir][PPtr]=Va;
  876.   for (i=0; i<Queue[desir]; i++)
  877.     if (Sockets[desir][i]>=0)
  878.       NbInQueue++;
  879.   PutInt(buf, GoodForPlay[desir]);
  880.   PutInt(buf+szi, NbInQueue);
  881.   *WhichQueue=desir;
  882.   write(sockfd, buf, QUEUE_BUF); /* ENVOI des donnees au client */
  883.  
  884.   for (i=0; i<Queue[desir]; i++)  /* on avertit les autres patients que l'on approche du but */
  885.     {
  886.       if (i!=PPtr && Sockets[desir][i]>=0)
  887.     {
  888.       PutInt(buf, NbInQueue);
  889.       write(Sockets[desir][i], buf, ENTIER_BUF);
  890.     }
  891.     }
  892.   
  893.   if (NbInQueue==GoodForPlay[desir])
  894.     return 1;
  895.   else
  896.     return 0;
  897. }
  898.  
  899.  
  900. void LoginProcedure(int accept_sockfd, int sockfd, int NBPLX)
  901. {
  902.   char buf[QUEUE_BUF], email[EMAILENGTH], Name[NAME_BUF];
  903.   int desir, nb_wanted, ZQ, Va, i;
  904.  
  905.   SendUniverseParameters(sockfd, &s_params);
  906.   SendMotd(sockfd);
  907.   SendQueueValues(sockfd);
  908.  
  909.   if ((Va=ReceiveName(sockfd, Name)) != -1 &&
  910.       MyRead(sockfd, email, EMAILENGTH, TIMEOUT) != -1)
  911.     {
  912.       MyRead(sockfd, buf, ENTIER_BUF, TIMEOUT);  /* queue... */
  913.       GetInt(buf, &desir);
  914.       MyRead(sockfd, buf, ENTIER_BUF, TIMEOUT);  /* nb de joueurs */
  915.       GetInt(buf, &nb_wanted);
  916.  
  917.       if (GetWhichQueue(sockfd, desir, nb_wanted, &ZQ, Name, email, Va))
  918.     if (fork()==0)
  919.       {
  920.         close(accept_sockfd);  /* child */
  921.         BeginTheGameServer(NBPLX, Clients[ZQ], Sockets[ZQ], GoodForPlay[ZQ], Names[ZQ], 
  922.                  V[ZQ],Emails[ZQ]);
  923.       }
  924.     else
  925.       {
  926.         for (i=0; i<GoodForPlay[ZQ]; i++)
  927.            close(Sockets[ZQ][i]);
  928.       }
  929.     
  930.       if (ZQ>-1 && Queue[ZQ]==GoodForPlay[ZQ])
  931.     {
  932.       Queue[ZQ]=0;
  933.       GoodForPlay[ZQ]=0;
  934.     }
  935.     }
  936. }
  937.  
  938.  
  939.  
  940. void InitQueues()
  941. {
  942.   int i;
  943.   for (i=0; i<MAX_QUEUES; i++)
  944.     {
  945.       Queue[i]=0;
  946.       GoodForPlay[i]=0;
  947.     }
  948. }
  949.  
  950. void DisplayHelp()
  951. {
  952.   printf("Usage : server -p<port>\n");
  953. }
  954.  
  955. void main(int argc, char *argv[])
  956. {
  957.   int i, PORTN=0, NBPLX=0, j=0;
  958.  
  959.   int sockfd, newsockfd, addrlen;
  960.   struct sockaddr_in serv_addr, client_addr;
  961.  
  962.   for (i=1; i<argc; i++)
  963.     if (!strncmp(argv[i], "-p", 2))
  964.       PORTN=atoi(argv[i]+2);
  965.   if (!PORTN)
  966.     {
  967.       DisplayHelp();
  968.       exit(0);
  969.     }
  970.  
  971.   InitQueues();
  972.   signal(SIGHUP, SIG_IGN);
  973.   signal(SIGPIPE, SIG_IGN);
  974.  
  975.   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  976.     {
  977.       fprintf(stderr, "** socket error (unable to create a socket) **\n");
  978.       exit(0);
  979.     }
  980.   
  981.   bzero(&serv_addr, sizeof(serv_addr));
  982.   serv_addr.sin_port = PORTN;
  983.   serv_addr.sin_family = AF_INET;
  984.                
  985.  
  986.   if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  987.     {
  988.       fprintf(stderr, "** bind error (probably bad port number) **\n");
  989.       exit(0);
  990.     }
  991.     
  992.   if (listen(sockfd, BACK_LOG) < 0)
  993.     {
  994.       fprintf(stderr, "** listen error **\n");
  995.       exit(0);
  996.     }
  997.  
  998.   ReadDefaultFile(&s_params);
  999.   nb_motd_lines=ReadMotdFile();
  1000.  
  1001.   NBPLX=s_params.SIZE_Z;
  1002.   if (NBPLX > MAX_LEVELS)
  1003.     {
  1004.       NBPLX=MAX_LEVELS;
  1005.       printf("Maximum number of levels : %d\n", MAX_LEVELS);
  1006.     }
  1007.  
  1008.   for (;;)
  1009.     {
  1010.       newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &addrlen);
  1011.       if (newsockfd < 0)
  1012.     continue;
  1013.       
  1014.       for (i=0; i<MAX_QUEUES; i++)  /* reception des sorties de queue */
  1015.     for (j=0; j<Queue[i]; j++)
  1016.       if (Sockets[i][j]>=0 && WaitForThisSocket(Sockets[i][j], 0))
  1017.         {
  1018.           Sockets[i][j]=(-1);
  1019.           close(Sockets[i][j]);
  1020.         }
  1021.       
  1022.       LoginProcedure(sockfd, newsockfd, NBPLX);
  1023.  
  1024.     }
  1025. }
  1026.